package hardware;

import java.awt.Color;
import java.awt.Font;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.LinkedList;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.omg.CORBA.CTX_RESTRICT_SCOPE;

public class GUI {

	private JFrame frame;
	private JPanel panel;
	private JPanel cachePanel;
	private JPanel memoryPanel;
	private JPanel archiPanel;
	private JPanel instPanel;
	private JPanel resPanel;
	private JPanel eduPanel;
	
	private JTextField size1;
	private JTextField line1;
	private JTextField m1;
	private JTextField time1;
	private JTextField size2;
	private JTextField line2;
	private JTextField m2;
	private JTextField time2;
	private JTextField size3;
	private JTextField line3;
	private JTextField m3;
	private JTextField time3;
	private JTextField memCap;
	private JTextField memTime;
	private JTextField pipeline;
	private JTextField reservStation;
	private JTextField rob;
	private JTextField addN;
	private JTextField mulN;
	private JTextField divN;
	private JTextField addEx;
	private JTextField mulEx;
	private JTextField divEx;
	private JComboBox rA;
	private JComboBox rB;
	private JComboBox rC;
	private JTextField r0;
	private JTextField r1;
	private JTextField r2;
	private JTextField r3;
	private JTextField r4;
	private JTextField r5;
	private JTextField r6;
	private JTextField r7;
	private JComboBox levels;
	private JCheckBox wb1;
	private JCheckBox wb2;
	private JCheckBox wb3;
	private JCheckBox wth1;
	private JCheckBox wth2;
	private JCheckBox wth3;
	private JTextField memAddress;
	private JTextField insBuffer;
	private JTextField value;
	private JTextField address;
	private JTextField immC;
	private JTextField immB;
	private JTextField cycles;
	private TextArea instText;
	
	private boolean edu = false;
	private int instCount = 0;
	private int caches = 0;
	private LinkedList<Instruction> instList = new LinkedList<Instruction>();
	private LinkedList<Data> dataList = new LinkedList<Data>();
	
	public GUI() throws Exception {
		initialize();
	}
	
	private void initialize() throws Exception {
		frame = new JFrame();
		frame.setTitle("Microprocessor");
		frame.setBounds(100, 100, 880, 645);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(null);
		frame.setVisible(true);
		
		panel = new JPanel();
		panel.setBounds(10, 11, 791, 440);		
		panel.setLayout(null);
		
		JLabel lblGucMicroprocessor = new JLabel("GUC Microprocessor");
		lblGucMicroprocessor.setFont(new Font("OCR A Extended", Font.BOLD | Font.ITALIC, 20));
		lblGucMicroprocessor.setBounds(73, 34, 265, 62);
		panel.add(lblGucMicroprocessor);
		
		// Initialise the 4 other views and call them from each other
		cacheView();
		memoryView();
		archiView();
		assemblyView();		
		
		JButton btnStartSimulation = new JButton("Standard Simulation");
		btnStartSimulation.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				// go to cache view
				frame.getContentPane().removeAll();				
				frame.getContentPane().add(cachePanel);
				frame.validate();
				frame.repaint();
				edu = false;
			}
		});
		btnStartSimulation.setBounds(287, 159, 212, 23);
		panel.add(btnStartSimulation);
		
		JButton btnNewButton = new JButton("Educational Simulation");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				frame.getContentPane().removeAll();				
				frame.getContentPane().add(cachePanel);
				frame.validate();
				frame.repaint();
				edu = true;
			}
		});
		btnNewButton.setBounds(287, 210, 212, 23);
		panel.add(btnNewButton);
		
		JButton prog1 = new JButton("Program 1");
		prog1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				try {
					Processor.program1();
					simulationView();
					instText.setVisible(true);
					instText.setText(Processor.getProgram1Inst());
					frame.getContentPane().removeAll();				
					frame.getContentPane().add(resPanel);
					frame.validate();
					frame.repaint();
				} catch (Exception e) {			
					e.printStackTrace();
				}
				
			}
		});
		prog1.setBounds(340, 255, 99, 23);
		panel.add(prog1);
		
		JButton prog2 = new JButton("Program 2");
		prog2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				try {
					Processor.program2();
					simulationView();
					instText.setVisible(true);
					instText.setText(Processor.getProgram2Inst());
					frame.getContentPane().removeAll();				
					frame.getContentPane().add(resPanel);
					frame.validate();
					frame.repaint();
				} catch (Exception e) {					
					e.printStackTrace();
				}
				
			}
		});
		prog2.setBounds(340, 300, 99, 23);
		panel.add(prog2);
		
		JButton btnProgram = new JButton("Program 3");
		btnProgram.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				try {
					Processor.program3();
					simulationView();
					instText.setVisible(true);
					instText.setText(Processor.getProgram3Inst());
					frame.getContentPane().removeAll();				
					frame.getContentPane().add(resPanel);
					frame.validate();
					frame.repaint();
				} catch (Exception e) {					
					e.printStackTrace();
				}
				
			}
		});
		btnProgram.setBounds(340, 345, 99, 23);
		panel.add(btnProgram);
		
		JButton btnExit = new JButton("Exit");
		btnExit.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				frame.setVisible(false);
				System.exit(0);
			}
		});
		btnExit.setBounds(340, 390, 99, 23);
		panel.add(btnExit);
		
		frame.getContentPane().add(panel);
		frame.validate();
		frame.repaint();
	}

	private void educationView() throws Exception{
		eduPanel = new JPanel();
		eduPanel.setBounds(10, 11, 844, 580);
		frame.getContentPane().removeAll();
		frame.getContentPane().add(eduPanel);
		frame.validate();
		frame.repaint();
		eduPanel.setLayout(null);
		
		JLabel lblEducationalView = new JLabel("Educational View:");
		lblEducationalView.setFont(new Font("OCR A Extended", Font.BOLD | Font.ITALIC, 16));
		lblEducationalView.setBounds(10, 11, 224, 33);
		eduPanel.add(lblEducationalView);
		
		JLabel lblEnterANumber = new JLabel("Enter a number the number of cycles to simulate.");
		lblEnterANumber.setBounds(81, 45, 405, 14);
		eduPanel.add(lblEnterANumber);
		
		JLabel lblSimulateFor = new JLabel("Simulate for:");
		lblSimulateFor.setBounds(10, 86, 85, 14);
		eduPanel.add(lblSimulateFor);
		
		cycles = new JTextField();
		cycles.setBounds(110, 83, 44, 20);
		eduPanel.add(cycles);
		cycles.setColumns(10);
		
		JLabel lblCycles = new JLabel("cycles");
		lblCycles.setBounds(164, 86, 46, 14);
		eduPanel.add(lblCycles);
		
		final TextArea reserveStat = new TextArea();
		reserveStat.setEditable(false);
		reserveStat.setBackground(Color.WHITE);		
		reserveStat.setBounds(10, 131, 304, 91);
		eduPanel.add(reserveStat);
		
		JLabel lblReservationStations = new JLabel("Reservation Stations:");
		lblReservationStations.setBounds(10, 111, 157, 14);
		eduPanel.add(lblReservationStations);
		
		JLabel lblCacheLevel1 = new JLabel("Cache Level 1:");
		lblCacheLevel1.setBounds(10, 228, 101, 14);
		eduPanel.add(lblCacheLevel1);				
		
		final TextArea cacheLevel1 = new TextArea();
		cacheLevel1.setEditable(false);
		cacheLevel1.setBackground(Color.WHITE);
		cacheLevel1.setBounds(10, 248, 304, 91);
		eduPanel.add(cacheLevel1);
		
		JLabel lblCacheLevel2 = new JLabel("Cache Level 2:");
		lblCacheLevel2.setBounds(10, 345, 89, 14);
		eduPanel.add(lblCacheLevel2);		
		
		final TextArea cacheLevel2 = new TextArea();
		cacheLevel2.setEditable(false);
		cacheLevel2.setBackground(Color.WHITE);
		cacheLevel2.setBounds(10, 365, 304, 82);
		eduPanel.add(cacheLevel2);
		
		if (caches == 1) {
			lblCacheLevel2.setVisible(false);
			cacheLevel2.setVisible(false);
		}
		
		JLabel lblCacheLevel3 = new JLabel("Cache Level 3:");
		lblCacheLevel3.setBounds(10, 453, 101, 14);		
		eduPanel.add(lblCacheLevel3);
		
		final TextArea cacheLevel3 = new TextArea();
		cacheLevel3.setBounds(10, 473, 304, 82);
		cacheLevel3.setBackground(Color.WHITE);
		eduPanel.add(cacheLevel3);
		
		if (caches == 1 || caches == 2) {			
			lblCacheLevel3.setVisible(false);
			cacheLevel3.setVisible(false);			
		}
		
		JLabel lblReorderBuffer = new JLabel("Re-Order Buffer:");
		lblReorderBuffer.setBounds(396, 345, 135, 14);
		eduPanel.add(lblReorderBuffer);
		
		final TextArea robs = new TextArea();
		robs.setEditable(false);
		robs.setBackground(Color.WHITE);
		robs.setBounds(396, 365, 380, 82);
		eduPanel.add(robs);
		
		JLabel lblMemory = new JLabel("Memory:");
		lblMemory.setBounds(396, 453, 90, 14);
		eduPanel.add(lblMemory);
		
		final TextArea memoryList = new TextArea();
		memoryList.setBounds(396, 473, 380, 82);
		memoryList.setEditable(false);
		memoryList.setBackground(Color.WHITE);
		eduPanel.add(memoryList);
		
		final TextArea instructionsList = new TextArea();
		instructionsList.setEditable(false);
		instructionsList.setBackground(Color.WHITE);
		instructionsList.setBounds(396, 131, 380, 208);
		eduPanel.add(instructionsList);
		
		JLabel lblInstructions = new JLabel("Instructions:");
		lblInstructions.setBounds(396, 111, 115, 14);
		eduPanel.add(lblInstructions);
		
		final JButton btnSimulate = new JButton("Simulate");
		btnSimulate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {				
					int cyc = Integer.parseInt(cycles.getText());
					try {
						Processor.simulate(cyc);
						boolean allCommit = true;
						for (int i = 0; i < Commit.instructions.size(); i++) {
							if (!Commit.instructions.get(i).isCommited()) {
								allCommit = false;
								break;
							}
						}
					if (allCommit && Fetch.instructions.isEmpty() && Decode.instructions.isEmpty()
							&& Issue.instructions .isEmpty() && Dispatch.instructions.isEmpty() && Execute.ins.isEmpty()) {
						System.out.println("DONE !");
						btnSimulate.setEnabled(false);
						reserveStat.setText("");
						rob.setText("");
						cacheLevel1.setText("");
						cacheLevel2.setText("");
						cacheLevel3.setText("");
						
						Instruction[] inst = new Instruction[Commit.instructions.size()];
						for (int i = 0; i < Commit.instructions.size(); i++) {
							inst[i] = Commit.instructions.get(i);
						}
						Arrays.sort(inst);
						instructionsList.setText("");
						for (int i = 0; i < inst.length; i++) {
							instructionsList.setText(instructionsList.getText() + "Instruction " + i + ": \n");
							instructionsList.setText(instructionsList.getText() + "	Fetch:    Start: " + inst[i].getFetchStartTime() + ", End: " + inst[i].getFetchEndTime() + "\n");
							instructionsList.setText(instructionsList.getText() + "	Decode:   Start: " + inst[i].getDecStartTime() + ", End: " + inst[i].getDecEndTime() + "\n");
							instructionsList.setText(instructionsList.getText() + "	Issue:    Start: " + inst[i].getIssueStartTime() + ", End: " + inst[i].getIssueEndTime() + "\n");
							instructionsList.setText(instructionsList.getText() + "	Dispatch: Start: " + inst[i].getDispStartTime() + ", End: " + inst[i].getDispEndTime() + "\n");
							instructionsList.setText(instructionsList.getText() + "	Execute:  Start: " + inst[i].getExecStartTime() + ", End: " + inst[i].getExecEndTime() + "\n");
							instructionsList.setText(instructionsList.getText() + "	Commit:   Start: " + inst[i].getCommitStartTime() + ", End: " + inst[i].getCommitEndTime() + "\n");
						}
						
						instructionsList.setText(instructionsList.getText() + "R0: " + Processor.reg0.value + "\n");
						instructionsList.setText(instructionsList.getText() + "R1: " + Processor.reg1.value + "\n");
						instructionsList.setText(instructionsList.getText() + "R2: " + Processor.reg2.value + "\n");
						instructionsList.setText(instructionsList.getText() + "R3: " + Processor.reg3.value + "\n");
						instructionsList.setText(instructionsList.getText() + "R4: " + Processor.reg4.value + "\n");
						instructionsList.setText(instructionsList.getText() + "R5: " + Processor.reg5.value + "\n");
						instructionsList.setText(instructionsList.getText() + "R6: " + Processor.reg6.value + "\n");
						instructionsList.setText(instructionsList.getText() + "R7: " + Processor.reg7.value + "\n");
						
						double CPI = inst[inst.length - 1].getCommitEndTime() / inst.length;
						instructionsList.setText(instructionsList.getText() + "Cycles per instruction: " + CPI + "\n");
						
						double IPC = 1.0 / CPI;
						DecimalFormat df = new DecimalFormat("0.0000");	
						instructionsList.setText(instructionsList.getText() + "Instructions per cycle: " + df.format(IPC) + "\n");

						DecimalFormat df2 = new DecimalFormat("0.00");
						if (Cache.l2Cache == null && Cache.l3Cache == null) { // level 1	
							double h1 = Cache.l1Cache.hit;
							double miss1 = Cache.l1Cache.miss;
							double hr1 = h1 / (h1 + miss1);
							double mr1 = 1 - hr1;
							double hI1 = Cache.l1Cache.hitI;
							double mI1 = Cache.l1Cache.missI;
							double hrI1 = hI1 / (hI1 + mI1);
							double mrI1 = 1 - hrI1;
							instructionsList.setText(instructionsList.getText() + "Cache level 1:  Hit ratio = " + df2.format(hr1) 
									+ " Miss ratio = " + df2.format(mr1) + "\nInstruction hit ratio = " + df2.format(hI1) 
									+ "Instruction miss ratio = " + df2.format(mrI1) + "\n");
							//at1.setText(Cache.l1Cache.accessTimes + "");
						} else if (Cache.l3Cache == null) { // level 2
							double h1 = Cache.l1Cache.hit;
							double miss1 = Cache.l1Cache.miss;
							double hr1 = h1 / (h1 + miss1);
							double mr1 = 1 - hr1;
							double hI1 = Cache.l1Cache.hitI;
							double mI1 = Cache.l1Cache.missI;
							double hrI1 = hI1 / (hI1 + mI1);
							double mrI1 = 1 - hrI1;
							instructionsList.setText(instructionsList.getText() + "Cache level 1:  Hit ratio = " + df2.format(hr1) 
									+ " Miss ratio = " + df2.format(mr1) + "\nInstruction hit ratio = " + df2.format(hI1) 
									+ "Instruction miss ratio = " + df2.format(mrI1) + "\n");
							//at1.setText(Cache.l1Cache.accessTimes + "");
							double h2 = Cache.l2Cache.hit;
							double miss2 = Cache.l2Cache.miss;
							double hr2 = h2 / (h2 + miss2);
							double mr2 = 1 - hr2;
							instructionsList.setText(instructionsList.getText() + "Cache level 2:  Hit ratio = " + df2.format(hr2) + " Miss ratio = " 
									+ df2.format(mr2) + "\n");
							//at2.setText(Cache.l2Cache.accessTimes + "");
						} else { // level 3			
							double h1 = Cache.l1Cache.hit;
							double miss1 = Cache.l1Cache.miss;
							double hr1 = h1 / (h1 + miss1);
							double mr1 = 1 - hr1;
							double hI1 = Cache.l1Cache.hitI;
							double mI1 = Cache.l1Cache.missI;
							double hrI1 = hI1 / (hI1 + mI1);
							double mrI1 = 1 - hrI1;
							System.out.println("aaaaaaaaaaa" + h1 + " " + miss1 + " " + Cache.l1Cache.accessTimes);
							System.out.println("aaaaaaaaaaa" + hI1 + " " + mI1 + " " + Cache.l1Cache.accessTimesI);
							instructionsList.setText(instructionsList.getText() + "Cache level 1:  Hit ratio = " + df2.format(hr1) 
									+ " Miss ratio = " + df2.format(mr1) + "\nInstruction hit ratio = " + df2.format(hI1) 
									+ "Instruction miss ratio = " + df2.format(mrI1) + "\n");
							//at1.setText(Cache.l1Cache.accessTimes + "");
							double h2 = Cache.l2Cache.hit;
							double miss2 = Cache.l2Cache.miss;
							double hr2 = h2 / (h2 + miss2);
							double mr2 = 1 - hr2;
							instructionsList.setText(instructionsList.getText() + "Cache level 2:  Hit ratio = " + df2.format(hr2) + " Miss ratio = " 
									+ df2.format(mr2) + "\n");
							//double h3 = Cache.l3Cache.hit;
							//double miss3 = Cache.l3Cache.miss;
							//double hr3 = h3 / (h3 + miss3);
							//double mr3 = 1 - hr3;
							//instructionsList.setText(instructionsList.getText() + "Cache level 3:  Hit ratio = " + df2.format(hr3) + " Miss ratio = " 
							//	+ df2.format(mr3) + "\n");
							
							//at2.setText(Cache.l2Cache.accessTimes + "");
						}
						
						memoryList.setText("");
						memoryList.setText(Processor.mem.toString());
					} else {
										
					Instruction[] inst = new Instruction[instList.size()];
					for (int i = 0; i < instList.size(); i++) {
						inst[i] = instList.get(i);
					}
					Arrays.sort(inst);
					
					instructionsList.setText("");
					boolean f = false;
					for (int i = 0; i < inst.length; i++) {
						//instructionsList.setText(instructionsList.getText() + "Instruction " + i + " is in the " + inst[i].getCurrentState() + "Stage.\n");						
						for (int j = 0; !f && j < Commit.instructions.size(); j++) {
							if (inst[i].equals(Commit.instructions.get(j))) {
								instructionsList.setText(instructionsList.getText() + "Instruction " + i + " is in the Commit Stage.\n");
								f = true; 
								break;
							}
						}
						for (int j = 0; !f && j < Execute.ins.size(); j++) {
							if (inst[i].equals(Execute.ins.get(j))) {
								instructionsList.setText(instructionsList.getText() + "Instruction " + i + " is in the Execute Stage.\n");
								f = true; 
								break;
							}
						}						
						for (int j = 0; !f && j < Issue.instructions.size(); j++) {
							if (inst[i].equals(Issue.instructions.get(j))) {
								instructionsList.setText(instructionsList.getText() + "Instruction " + i + " is in the Issue Stage.\n");
								f = true; 
								break;
							}
						}						
						for (int j = 0; !f && j < Dispatch.instructions.size(); j++) {
							if (inst[i].equals(Dispatch.instructions.get(j))) {
								instructionsList.setText(instructionsList.getText() + "Instruction " + i + " is in the Dispatch Stage.\n");
								f = true; 
								break;
							}
						}						
						for (int j = 0; !f && j < Decode.instructions.size(); j++) {
							if (inst[i].equals(Decode.instructions.get(j))) {
								instructionsList.setText(instructionsList.getText() + "Instruction " + i + " is in the Decode Stage.\n");
								f = true; 
								break;
							}
						}						
						for (int j = 0; !f && j < Fetch.instructions.size(); j++) {
							if (inst[i].equals(Fetch.instructions.get(j))) {
								instructionsList.setText(instructionsList.getText() + "Instruction " + i + " is in the Fetch Stage.\n");
								f = true; 
								break;
							}
						}								
					}
					robs.setText("");
					for (int i = 0; i < Processor.rob.size(); i++) {
						robs.setText(robs.getText() +  Processor.rob.get(i).toString() + "\n");
					}
					
					reserveStat.setText("");
					for (int i = 0; i < Processor.reservationStations.size(); i++) {
						if (Processor.reservationStations.get(i).getIns() != null) 
							reserveStat.setText(reserveStat.getText() +  Processor.reservationStations.get(i).toString() + "\n");
					}
					
					if (caches == 1) {
						cacheLevel1.setText("");
						cacheLevel1.setText(Cache.l1Cache.toString());
					} else if (caches == 2) {
						cacheLevel1.setText("");
						cacheLevel1.setText(Cache.l1Cache.toString());
						cacheLevel2.setText("");
						cacheLevel2.setText(Cache.l2Cache.toString());
					} else if (caches == 3) {
						cacheLevel1.setText("");
						cacheLevel1.setText(Cache.l1Cache.toString());
						cacheLevel2.setText("");
						cacheLevel2.setText(Cache.l2Cache.toString());
						cacheLevel3.setText("");
						cacheLevel3.setText(Cache.l3Cache.toString());
					}
					
					memoryList.setText("");
					memoryList.setText(Processor.mem.toString());
					
					}
				
				} catch (Exception e) {						
					//e.printStackTrace();
				}
			}
				// clear the text area 
				// view the RS, ROB, CACHE, MEM, INST.
			
		});
		btnSimulate.setBounds(225, 82, 89, 23);
		eduPanel.add(btnSimulate);
	}
	
	private void simulationView() throws Exception {
		resPanel = new JPanel();
		resPanel.setBounds(10, 11, 791, 540);
		frame.getContentPane().removeAll();
		frame.getContentPane().add(resPanel);
		frame.validate();
		frame.repaint();
		resPanel.setLayout(null);
		
		JLabel label = new JLabel("Simulation Results:");
		label.setFont(new Font("OCR A Extended", Font.BOLD | Font.ITALIC, 16));
		label.setBounds(10, 11, 267, 58);
		resPanel.add(label);
		
		TextArea resultPanel = new TextArea();
		resultPanel.setBackground(Color.WHITE);
		resultPanel.setForeground(Color.BLUE);
		resultPanel.setEditable(false);
		resultPanel.setBounds(321, 202, 460, 328);
		resPanel.add(resultPanel);
		
		JLabel lblFinalDisplays = new JLabel("Final displays:");
		lblFinalDisplays.setBounds(321, 179, 152, 14);
		resPanel.add(lblFinalDisplays);
		
		JLabel executionTime = new JLabel("Execution time: ");
		executionTime.setBounds(20, 85, 215, 14);
		resPanel.add(executionTime);
		
		JLabel cpi = new JLabel("Cycles per instruction: ");
		cpi.setBounds(20, 120, 200, 14);
		resPanel.add(cpi);
		
		JLabel ipc = new JLabel("Instructions per cycle: ");
		ipc.setBounds(20, 155, 200, 14);
		resPanel.add(ipc);
		
		JLabel cl1 = new JLabel(" Cache level 1:");
		cl1.setBounds(246, 85, 88, 14);
		resPanel.add(cl1);
		
		JLabel cl2 = new JLabel("Cache level 2:");
		if (Cache.l2Cache == null) {
			cl2.setVisible(false);
		}
		cl2.setBounds(246, 120, 89, 14);
		resPanel.add(cl2);
		
		instText = new TextArea();
		instText.setForeground(Color.RED);
		instText.setBackground(Color.WHITE);
		instText.setEditable(false);
		instText.setBounds(24, 202, 253, 220);
		resPanel.add(instText);
		
//		JLabel lblCacheLevel = new JLabel("Cache level 3:");
//		lblCacheLevel.setBounds(246, 155, 90, 14);
//		if (caches == 1 || caches == 2) {
//			lblCacheLevel.setVisible(false);
//		}
//		resPanel.add(lblCacheLevel);
		
		JLabel lblHitRatio = new JLabel("Hit Ratio");
		lblHitRatio.setBounds(360, 56, 98, 14);
		resPanel.add(lblHitRatio);
		
		JLabel lblMissRatio = new JLabel("Miss Ratio");
		lblMissRatio.setBounds(480, 56, 98, 14);
		resPanel.add(lblMissRatio);
		
		JLabel c1H = new JLabel("");
		c1H.setBounds(366, 85, 46, 14);
		resPanel.add(c1H);
		
		JLabel c1M = new JLabel("");
		c1M.setBounds(486, 85, 46, 14);
		resPanel.add(c1M);
		
		JLabel c2H = new JLabel("");
		c2H.setBounds(366, 120, 46, 14);
		resPanel.add(c2H);
		
		JLabel c2M = new JLabel("");
		c2M.setBounds(486, 120, 46, 14);
		resPanel.add(c2M);
		
//		JLabel c3H = new JLabel("");
//		c3H.setBounds(366, 155, 46, 14);
//		resPanel.add(c3H);
//		
//		JLabel c3M = new JLabel("");
//		c3M.setBounds(486, 155, 46, 14);
//		resPanel.add(c3M);
		
//		JLabel lblAccessTime = new JLabel("Access Time");
//		lblAccessTime.setBounds(560, 56, 88, 14);
//		resPanel.add(lblAccessTime);
//		
//		JLabel at1 = new JLabel("");
//		at1.setBounds(568, 85, 46, 14);
//		resPanel.add(at1);
//		
//		JLabel at2 = new JLabel("");
//		at2.setBounds(568, 120, 46, 14);
//		resPanel.add(at2);
		
//		JLabel at3 = new JLabel("");
//		at3.setBounds(568, 155, 46, 14);
//		resPanel.add(at3);
		
		Processor.simulate(100000);
		
		System.out.println("Done " + Commit.instructions.size());
		resultPanel.setText("");				
		
		Instruction[] inst = new Instruction[Commit.instructions.size()];
		for (int i = 0; i < Commit.instructions.size(); i++) {
			inst[i] = Commit.instructions.get(i);
		}				
		Arrays.sort(inst);
		executionTime.setText(executionTime.getText() + inst[inst.length - 1].getCommitEndTime());
		
		double CPI = inst[inst.length - 1].getCommitEndTime() / inst.length;
		cpi.setText(cpi.getText() + CPI);
		
		double IPC = 1.0 / CPI;
		DecimalFormat df = new DecimalFormat("0.0000");	
		ipc.setText(ipc.getText() + df.format(IPC));

		DecimalFormat df2 = new DecimalFormat("0.00");
		if (Cache.l2Cache == null && Cache.l3Cache == null) { // level 1	
			double h1 = Cache.l1Cache.hit;
			double miss1 = Cache.l1Cache.miss;
			double hr1 = h1 / (h1 + miss1);
			double mr1 = 1 - hr1;
			double hI1 = Cache.l1Cache.hitI;
			double mI1 = Cache.l1Cache.missI;
			double hrI1 = hI1 / (hI1 + mI1);
			double mrI1 = 1 - hrI1;
			c1H.setText(df2.format(hr1) + ", " + df2.format(hrI1));
			c1M.setText(df2.format(mr1) + ", " + df2.format(mrI1));
			//at1.setText(Cache.l1Cache.accessTimes + "");
		} else if (Cache.l3Cache == null) { // level 2
			double h1 = Cache.l1Cache.hit;
			double miss1 = Cache.l1Cache.miss;
			double hr1 = h1 / (h1 + miss1);
			double mr1 = 1 - hr1;
			double hI1 = Cache.l1Cache.hitI;
			double mI1 = Cache.l1Cache.missI;
			double hrI1 = hI1 / (hI1 + mI1);
			double mrI1 = 1 - hrI1;
			c1H.setText(df2.format(hr1) + ", " + df2.format(hrI1));
			c1M.setText(df2.format(mr1) + ", " + df2.format(mrI1));
			//at1.setText(Cache.l1Cache.accessTimes + "");
			double h2 = Cache.l2Cache.hit;
			double miss2 = Cache.l2Cache.miss;
			double hr2 = h2 / (h2 + miss2);
			double mr2 = 1 - hr2;
			c2H.setText(df2.format(hr2));
			c2M.setText(df2.format(mr2));
			//at2.setText(Cache.l2Cache.accessTimes + "");
		} else { // level 3			
			double h1 = Cache.l1Cache.hit;
			double miss1 = Cache.l1Cache.miss;
			double hr1 = h1 / (h1 + miss1);
			double mr1 = 1 - hr1;
			double hI1 = Cache.l1Cache.hitI;
			double mI1 = Cache.l1Cache.missI;
			double hrI1 = hI1 / (hI1 + mI1);
			double mrI1 = 1 - hrI1;
			System.out.println("aaaaaaaaaaa" + h1 + " " + miss1 + " " + Cache.l1Cache.accessTimes);
			System.out.println("aaaaaaaaaaa" + hI1 + " " + mI1 + " " + Cache.l1Cache.accessTimesI);
			c1H.setText(df2.format(hr1) + ", " + df2.format(hrI1));
			c1M.setText(df2.format(mr1) + ", " + df2.format(mrI1));
			//at1.setText(Cache.l1Cache.accessTimes + "");
			double h2 = Cache.l2Cache.hit;
			double miss2 = Cache.l2Cache.miss;
			double hr2 = h2 / (h2 + miss2);
			double mr2 = 1 - hr2;
			c2H.setText(df2.format(hr2));
			c2M.setText(df2.format(mr2));
			//at2.setText(Cache.l2Cache.accessTimes + "");
		}
		
		for (int i = 0; i < inst.length; i++) {
			resultPanel.setText(resultPanel.getText() + "Instruction " + i + ": \n");
			resultPanel.setText(resultPanel.getText() + "	Fetch:    Start: " + inst[i].getFetchStartTime() + ", End: " + inst[i].getFetchEndTime() + "\n");
			resultPanel.setText(resultPanel.getText() + "	Decode:   Start: " + inst[i].getDecStartTime() + ", End: " + inst[i].getDecEndTime() + "\n");
			resultPanel.setText(resultPanel.getText() + "	Issue:    Start: " + inst[i].getIssueStartTime() + ", End: " + inst[i].getIssueEndTime() + "\n");
			resultPanel.setText(resultPanel.getText() + "	Dispatch: Start: " + inst[i].getDispStartTime() + ", End: " + inst[i].getDispEndTime() + "\n");
			resultPanel.setText(resultPanel.getText() + "	Execute:  Start: " + inst[i].getExecStartTime() + ", End: " + inst[i].getExecEndTime() + "\n");
			resultPanel.setText(resultPanel.getText() + "	Commit:   Start: " + inst[i].getCommitStartTime() + ", End: " + inst[i].getCommitEndTime() + "\n");
		}	
		
		resultPanel.setText(resultPanel.getText() + "R0: " + Processor.reg0.value + "\n");
		resultPanel.setText(resultPanel.getText() + "R1: " + Processor.reg1.value + "\n");
		resultPanel.setText(resultPanel.getText() + "R2: " + Processor.reg2.value + "\n");
		resultPanel.setText(resultPanel.getText() + "R3: " + Processor.reg3.value + "\n");
		resultPanel.setText(resultPanel.getText() + "R4: " + Processor.reg4.value + "\n");
		resultPanel.setText(resultPanel.getText() + "R5: " + Processor.reg5.value + "\n");
		resultPanel.setText(resultPanel.getText() + "R6: " + Processor.reg6.value + "\n");
		resultPanel.setText(resultPanel.getText() + "R7: " + Processor.reg7.value + "\n");
		
	}

	
	private void assemblyView() {		
		instPanel = new JPanel();
		instPanel.setBounds(10, 11, 791, 440);		
		instPanel.setLayout(null);
		
		JLabel lblAssemblyProgram = new JLabel("Assembly Program:");
		lblAssemblyProgram.setFont(new Font("OCR A Extended", Font.BOLD | Font.ITALIC, 16));
		lblAssemblyProgram.setBounds(10, 11, 224, 33);
		instPanel.add(lblAssemblyProgram);
		
		JLabel lblMemoryStartAddress = new JLabel("Memory start address:");
		lblMemoryStartAddress.setBounds(34, 55, 133, 14);
		instPanel.add(lblMemoryStartAddress);
		
		memAddress = new JTextField();
		memAddress.setBounds(231, 52, 44, 20);
		instPanel.add(memAddress);
		memAddress.setColumns(10);
		
		final JLabel memAddReq = new JLabel("required");
		memAddReq.setForeground(Color.RED);
		memAddReq.setVisible(false);
		memAddReq.setFont(new Font("Tahoma", Font.ITALIC, 11));
		memAddReq.setBounds(342, 55, 46, 14);
		instPanel.add(memAddReq);
		
		JLabel lblLoadDataIn = new JLabel("Load data in memory");
		lblLoadDataIn.setBounds(610, 83, 152, 14);
		instPanel.add(lblLoadDataIn);
		
		value = new JTextField();
		value.setBounds(682, 108, 44, 20);
		instPanel.add(value);
		value.setColumns(10);
		
		JLabel lblValue = new JLabel("Value:");
		lblValue.setBounds(596, 111, 46, 14);
		instPanel.add(lblValue);
		
		JLabel lblAddress = new JLabel("Address:");
		lblAddress.setBounds(596, 140, 65, 14);
		instPanel.add(lblAddress);
		
		address = new JTextField();
		address.setBounds(682, 137, 44, 20);
		instPanel.add(address);
		address.setColumns(10);				
		
		final TextArea memDataLog = new TextArea();
		memDataLog.setEditable(false);
		memDataLog.setBounds(560, 225, 205, 158);
		instPanel.add(memDataLog);
		
		// memory load button
		JButton btnNewButton = new JButton("ADD");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {				
				boolean valid = true;
				try {
					Integer.parseInt(value.getText());
					Integer.parseInt(address.getText());
				} catch (Exception e) {
					valid = false;
				}
				if (valid) {
					int add = Integer.parseInt(address.getText());
					int val = Integer.parseInt(value.getText());
					dataList.addLast(new Data(add, val));
					String s = "Added " + value.getText() + " to memory address " + address.getText() + "\n";
					memDataLog.setText(memDataLog.getText() + s);
					value.setText("");
					address.setText("");
				}			
			}
		});
		btnNewButton.setBounds(629, 172, 71, 23);
		instPanel.add(btnNewButton);
		
		JLabel lblInstructions = new JLabel("Instruction");
		lblInstructions.setBounds(34, 111, 76, 14);
		instPanel.add(lblInstructions);
		
		final TextArea instLog = new TextArea();
		instLog.setEditable(false);
		instLog.setBounds(34, 225, 258, 158);
		instPanel.add(instLog);				
		
		JButton button = new JButton("<- Back");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				frame.getContentPane().removeAll();				
				frame.getContentPane().add(archiPanel);
				frame.validate();
				frame.repaint();
			}
		});
		button.setBounds(30, 400, 89, 23);
		instPanel.add(button);				
		
		JLabel lblRega = new JLabel("RegA");
		lblRega.setBounds(148, 111, 65, 14);
		instPanel.add(lblRega);
		
		rA = new JComboBox();
		rA.setModel(new DefaultComboBoxModel(new String[] {"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7"}));
		rA.setBounds(148, 137, 45, 20);
		instPanel.add(rA);
		
		final JLabel lblRegb = new JLabel("RegB");
		lblRegb.setBounds(229, 111, 46, 14);
		instPanel.add(lblRegb);
		
		rB = new JComboBox();
		rB.setModel(new DefaultComboBoxModel(new String[] {"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7"}));
		rB.setBounds(230, 137, 45, 20);
		instPanel.add(rB);
		
		final JLabel lblRegc = new JLabel("RegC");
		lblRegc.setBounds(305, 111, 46, 14);
		instPanel.add(lblRegc);
		
		rC = new JComboBox();
		rC.setModel(new DefaultComboBoxModel(new String[] {"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7"}));
		rC.setBounds(306, 137, 45, 20);
		instPanel.add(rC);
		
		immB = new JTextField();
		immB.setBounds(231, 168, 44, 20);
		immB.setVisible(false);
		instPanel.add(immB);
		immB.setColumns(10);
		
		immC = new JTextField();
		immC.setBounds(302, 168, 44, 20);
		immC.setVisible(false);
		instPanel.add(immC);
		immC.setColumns(10);
		
		final JComboBox instruction = new JComboBox();
		instruction.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
			if (instruction.getSelectedIndex() == 0 || instruction.getSelectedIndex() == 2 || instruction.getSelectedIndex() == 3
						|| instruction.getSelectedIndex() == 4) {					
				lblRegc.setText("RegC");
				lblRegc.setVisible(true);
				lblRegb.setVisible(true);
				immC.setVisible(false);
				immB.setVisible(false);
				rC.setVisible(true);
				rB.setVisible(true);
			} else if(instruction.getSelectedIndex() == 1 || instruction.getSelectedIndex() == 5 || instruction.getSelectedIndex() == 6
					|| instruction.getSelectedIndex() == 7) {
				lblRegc.setText("imm");
				lblRegc.setVisible(true);
				lblRegb.setVisible(true);
				immC.setVisible(true);
				immB.setVisible(false);
				rC.setVisible(false);
				rB.setVisible(true);
			} else if(instruction.getSelectedIndex() == 8) {				
				lblRegc.setVisible(false);
				lblRegb.setText("imm");
				lblRegb.setVisible(true);
				immC.setVisible(false);
				immB.setVisible(true);
				rC.setVisible(false);
				rB.setVisible(false);
			} else if(instruction.getSelectedIndex() == 9) {
				lblRegc.setVisible(false);
				lblRegb.setText("RegB");
				lblRegb.setVisible(true);
				immC.setVisible(false);
				immB.setVisible(false);
				rC.setVisible(false);
				rB.setVisible(true);
			} else if(instruction.getSelectedIndex() == 10) {
				lblRegc.setVisible(false);				
				lblRegb.setVisible(false);	
				immC.setVisible(false);
				immB.setVisible(false);
				rC.setVisible(false);
				rB.setVisible(false);
			}
			}
		});
		instruction.setModel(new DefaultComboBoxModel(new String[] {"ADD", "ADDI", "NAND", "MUL", "DIV", "LW", "SW", "BEQ", "JMP", "JALR", "RET"}));
		instruction.setBounds(32, 137, 78, 20);
		instPanel.add(instruction);
		
		JButton btnClear = new JButton("Clear");
		btnClear.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				instList.clear();
				instLog.setText("");
			}
		});
		btnClear.setBounds(231, 389, 70, 23);
		instPanel.add(btnClear);
		
		JButton addInst = new JButton("ADD");
		addInst.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {				
				Register a;
				Register b;
				Register c;
				if (rA.getSelectedIndex() == 0) {
					a = Processor.reg0;
				} else if (rA.getSelectedIndex() == 1) {
					a = Processor.reg1;
				} else if (rA.getSelectedIndex() == 2) {
					a = Processor.reg2;
				} else if (rA.getSelectedIndex() == 3) {
					a = Processor.reg3;
				} else if (rA.getSelectedIndex() == 4) {
					a = Processor.reg4;
				} else if (rA.getSelectedIndex() == 5) {
					a = Processor.reg5;
				} else if (rA.getSelectedIndex() == 6) {
					a = Processor.reg6;
				} else {
					a = Processor.reg7;
				} 
				if (rB.getSelectedIndex() == 0) {
					b = Processor.reg0;
				} else if (rB.getSelectedIndex() == 1) {
					b = Processor.reg1;
				} else if (rB.getSelectedIndex() == 2) {
					b = Processor.reg2;
				} else if (rB.getSelectedIndex() == 3) {
					b = Processor.reg3;
				} else if (rB.getSelectedIndex() == 4) {
					b = Processor.reg4;
				} else if (rB.getSelectedIndex() == 5) {
					b = Processor.reg5;
				} else if (rB.getSelectedIndex() == 6) {
					b = Processor.reg6;
				} else {
					b = Processor.reg7;
				} 
				if (rC.getSelectedIndex() == 0) {
					c = Processor.reg0;
				} else if (rC.getSelectedIndex() == 1) {
					c = Processor.reg1;
				} else if (rC.getSelectedIndex() == 2) {
					c = Processor.reg2;
				} else if (rC.getSelectedIndex() == 3) {
					c = Processor.reg3;
				} else if (rC.getSelectedIndex() == 4) {
					c = Processor.reg4;
				} else if (rC.getSelectedIndex() == 5) {
					c = Processor.reg5;
				} else if (rC.getSelectedIndex() == 6) {
					c = Processor.reg6;
				} else {
					c = Processor.reg7;
				} 
				if (instruction.getSelectedIndex() == 0 || instruction.getSelectedIndex() == 2 || instruction.getSelectedIndex() == 3
						|| instruction.getSelectedIndex() == 4) { // ADD NAND MUL DIV								
					int exTime = 0;
					if (instruction.getSelectedIndex() == 0) 
						exTime = Integer.parseInt(addEx.getText());
					else if (instruction.getSelectedIndex() == 2) 
						exTime = 1;
					else if (instruction.getSelectedIndex() == 3) 
						exTime = Integer.parseInt(mulEx.getText());
					else if (instruction.getSelectedIndex() == 4) 
						exTime = Integer.parseInt(divEx.getText());
					Instruction i = new Instruction(instCount, instruction.getSelectedItem()+"", a, b, c, 0, exTime);
					instList.addLast(i);					
					instCount++;
					String s = instruction.getSelectedItem() + " " + rA.getSelectedItem() +  " " 
						+ rB.getSelectedItem() + " " + rC.getSelectedItem() + "\n";
					instLog.setText(instLog.getText() + s);
					frame.validate();
					frame.repaint();					
			} else if(instruction.getSelectedIndex() == 1 || instruction.getSelectedIndex() == 5 || instruction.getSelectedIndex() == 6
					|| instruction.getSelectedIndex() == 7) { // ADDI LW SW BEQ							
				int exTime = 0;
				if (instruction.getSelectedIndex() == 1) 
					exTime = Integer.parseInt(addEx.getText());
				else if (instruction.getSelectedIndex() == 7) 
					exTime = 1;				
				if (!immC.getText().equals("")) {
					Instruction i = new Instruction(instCount, instruction.getSelectedItem()+"", a, b, null, Integer.parseInt(immC.getText()),exTime);	
					instList.addLast(i);
					instCount++;
				}				
				String s = instruction.getSelectedItem() + " " + rA.getSelectedItem() +  " " 
					+ rB.getSelectedItem() + " #" + immC.getText() + "\n";
				instLog.setText(instLog.getText() + s);
				frame.validate();
				frame.repaint();				
			} else if(instruction.getSelectedIndex() == 8) { // JMP								
				if (!immB.getText().equals("")) {
					Instruction i = new Instruction(instCount, instruction.getSelectedItem()+"", a, null, null, Integer.parseInt(immB.getText()),1);
					instList.addLast(i);
					instCount++;
				}				
				String s = instruction.getSelectedItem() + " " + rA.getSelectedItem() +  " #" 
					+ immB.getText() + "\n";
				instLog.setText(instLog.getText() + s);
				frame.validate();
				frame.repaint();				
			} else if(instruction.getSelectedIndex() == 9) { // JALR				
				Instruction i = new Instruction(instCount, instruction.getSelectedItem()+"", a, b, null, 0,1);
				instList.addLast(i);
				instCount++;
				String s = instruction.getSelectedItem() + " " + rA.getSelectedItem() +  " " 
					+ rB.getSelectedItem() + "\n";
				instLog.setText(instLog.getText() + s);
				frame.validate();
				frame.repaint();				
			} else if(instruction.getSelectedIndex() == 10) { // RET																
				Instruction i = new Instruction(instCount, instruction.getSelectedItem()+"", a, null, null, 0,1);
				instList.addLast(i);
				instCount++;
				String s = instruction.getSelectedItem() + " " + rA.getSelectedItem() + "\n";
				instLog.setText(instLog.getText() + s);
				frame.validate();
				frame.repaint();
			}				
			}
		});				
		addInst.setBounds(117, 183, 89, 23);
		instPanel.add(addInst);
		
		JLabel lblRegisterData = new JLabel("Register data");
		lblRegisterData.setBounds(390, 111, 89, 14);
		instPanel.add(lblRegisterData);
		
		JLabel lblR = new JLabel("R0:");
		lblR.setBounds(390, 140, 46, 14);
		instPanel.add(lblR);
		
		JLabel lblR_1 = new JLabel("R1:");
		lblR_1.setBounds(390, 171, 46, 14);
		instPanel.add(lblR_1);
		
		JLabel lblR_2 = new JLabel("R2:");
		lblR_2.setBounds(390, 203, 46, 14);
		instPanel.add(lblR_2);
		
		JLabel lblR_3 = new JLabel("R3:");
		lblR_3.setBounds(390, 234, 46, 14);
		instPanel.add(lblR_3);
		
		JLabel lblR_4 = new JLabel("R4:");
		lblR_4.setBounds(390, 259, 46, 14);
		instPanel.add(lblR_4);
		
		JLabel lblR_5 = new JLabel("R5:");
		lblR_5.setBounds(390, 284, 46, 14);
		instPanel.add(lblR_5);
		
		JLabel lblR_6 = new JLabel("R6:");
		lblR_6.setBounds(390, 310, 46, 14);
		instPanel.add(lblR_6);
		
		JLabel lblR_7 = new JLabel("R7:");
		lblR_7.setBounds(390, 335, 46, 14);
		instPanel.add(lblR_7);
		
		r0 = new JTextField();
		r0.setBounds(425, 137, 46, 20);
		instPanel.add(r0);
		r0.setText("0");
		r0.setColumns(10);
		
		r1 = new JTextField();
		r1.setText("0");		
		r1.setBounds(425, 173, 46, 20);
		instPanel.add(r1);
		r1.setColumns(10);
		
		r2 = new JTextField("0");
		r2.setBounds(425, 200, 46, 20);
		instPanel.add(r2);
		r2.setText("0");
		r2.setColumns(10);
		
		r3 = new JTextField("0");
		r3.setBounds(425, 231, 46, 20);
		instPanel.add(r3);
		r3.setText("0");
		r3.setColumns(10);
		
		r4 = new JTextField("0");
		r4.setText("");
		r4.setBounds(425, 259, 46, 20);
		instPanel.add(r4);
		r4.setText("0");
		r4.setColumns(10);
		
		r5 = new JTextField("0");
		r5.setBounds(425, 284, 46, 20);
		instPanel.add(r5);
		r5.setText("0");
		r5.setColumns(10);
		
		r6 = new JTextField("0");
		r6.setText("");
		r6.setBounds(425, 309, 46, 20);
		r6.setText("0");
		instPanel.add(r6);
		r6.setColumns(10);
		
		r7 = new JTextField("0");
		r7.setText("");
		r7.setBounds(425, 335, 46, 20);
		r7.setText("0");
		instPanel.add(r7);
		r7.setColumns(10);

		
		JButton btnFinish = new JButton("Finish");
		btnFinish.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				boolean valid = true;
				if (memAddress.getText().equals("")) {
					memAddReq.setVisible(true);
					valid = false;
				} else {
					memAddReq.setVisible(false);
				}
				try {
					Integer.parseInt(memAddress.getText());	
					Integer.parseInt(r0.getText());
					Integer.parseInt(r1.getText());
					Integer.parseInt(r2.getText());
					Integer.parseInt(r3.getText());
					Integer.parseInt(r4.getText());
					Integer.parseInt(r5.getText());
					Integer.parseInt(r6.getText());
					Integer.parseInt(r7.getText());
				} catch (Exception e) {
					valid = false;
				}
				if (valid) {
					//```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````					
					Cache c;
					// initialise the caches	
					if (levels.getSelectedIndex() == 0) {
						String wpo = "";
						if (wb1.isSelected()) 
							wpo = L1Cache.WRITE_BACK;
						else
							wpo = L1Cache.WRITE_THROUGH;
						int s = Integer.parseInt(size1.getText());
						int l = Integer.parseInt(line1.getText());
						int m = Integer.parseInt(m1.getText());
						int cyc = Integer.parseInt(time1.getText());
						System.out.println("Cache level 1" + wpo + " " + s + " " + l + " " + m + " " + cyc);
						L1Cache nc = new L1Cache(wpo, cyc, s, l, m);				    	
				    	Fetch.l1Cache = nc;
				    	Processor.nc = nc;
				    	caches = 1;
				    	c = new Cache(1, nc, null, null);
					} else if (levels.getSelectedIndex() == 1) {
						String wpo = "";
						if (wb1.isSelected()) 
							wpo = L1Cache.WRITE_BACK;
						else
							wpo = L1Cache.WRITE_THROUGH;
						int s = Integer.parseInt(size1.getText());
						int l = Integer.parseInt(line1.getText());
						int m = Integer.parseInt(m1.getText());
						int cyc = Integer.parseInt(time1.getText());
						System.out.println("Cache level 1" + wpo + " " + s + " " + l + " " + m + " " + cyc);
						L1Cache nc = new L1Cache(wpo, cyc, s, l, m);
						wpo = "";
						if (wb2.isSelected()) 
							wpo = L1Cache.WRITE_BACK;
						else
							wpo = L1Cache.WRITE_THROUGH;
						s = Integer.parseInt(size2.getText());
						l = Integer.parseInt(line2.getText());
						m = Integer.parseInt(m2.getText());
						cyc = Integer.parseInt(time2.getText());
						System.out.println("Cache level 2" + wpo + " " + s + " " + l + " " + m + " " + cyc);
						L2Cache nc2 = new L2Cache(wpo, cyc, s, l, m);						
				    	nc2.setL1(nc);
				    	nc.setL2(nc2);				    	
				    	Fetch.l2Cache = nc2;
				    	Fetch.l1Cache = nc;
				    	Processor.nc = nc;
				    	Processor.nc2 = nc2;
				    	caches = 2;
				    	c = new Cache(2, nc, nc2, null);
					} else if (levels.getSelectedIndex() == 2){
						String wpo = "";
						if (wb1.isSelected()) 
							wpo = L1Cache.WRITE_BACK;
						else
							wpo = L1Cache.WRITE_THROUGH;
						int s = Integer.parseInt(size1.getText());
						int l = Integer.parseInt(line1.getText());
						int m = Integer.parseInt(m1.getText());
						int cyc = Integer.parseInt(time1.getText());
						System.out.println("Cache level 1" + wpo + " " + s + " " + l + " " + m + " " + cyc);
						L1Cache nc = new L1Cache(wpo, cyc, s, l, m);
						wpo = "";
						if (wb2.isSelected()) {
							wpo = L1Cache.WRITE_BACK;
						} else {
							wpo = L1Cache.WRITE_THROUGH;
						}
						s = Integer.parseInt(size2.getText());
						l = Integer.parseInt(line2.getText());
						m = Integer.parseInt(m2.getText());
						cyc = Integer.parseInt(time2.getText());
						System.out.println("Cache level 2" + wpo + " " + s + " " + l + " " + m + " " + cyc);
						L2Cache nc2 = new L2Cache(wpo, cyc, s, l, m);
						wpo = "";
						if (wb3.isSelected()) {
							wpo = L1Cache.WRITE_BACK;
						}else{
							wpo = L1Cache.WRITE_THROUGH;
						}
						s = Integer.parseInt(size3.getText());
						l = Integer.parseInt(line3.getText());
						m = Integer.parseInt(m3.getText());
						cyc = Integer.parseInt(time3.getText());
						System.out.println("Cache level 3" + wpo + " " + s + " " + l + " " + m + " " + cyc);
						L3Cache nc3 = new L3Cache(wpo, cyc, s, l, m);
						nc3.setL1(nc);
				    	nc3.setL2(nc2);
				    	nc2.setL3(nc3);
				    	nc2.setL1(nc);
				    	nc.setL2(nc2);
				    	nc.setL3(nc3);
				    	Fetch.l3Cache = nc3;
				    	Fetch.l2Cache = nc2;
				    	Fetch.l1Cache = nc;
				    	Processor.nc = nc;
				    	Processor.nc2 = nc2;
				    	Processor.nc3 = nc3;
				    	caches = 3;
				    	c = new Cache(3, nc, nc2, nc3);
					}					
					int pMemCap = Integer.parseInt(memCap.getText()); 
					int pMemTime = Integer.parseInt(memTime.getText());
					System.out.println("memory size " + pMemCap + " time "+ pMemTime);
					Memory.programSize = instList.size();			    	
					Processor.mem = new Memory(pMemCap, pMemTime);
					
					Processor.reg0.value = Integer.parseInt(r0.getText());
					Processor.reg1.value = Integer.parseInt(r1.getText());
					Processor.reg2.value = Integer.parseInt(r2.getText());
					Processor.reg3.value = Integer.parseInt(r3.getText());
					Processor.reg4.value = Integer.parseInt(r4.getText());
					Processor.reg5.value = Integer.parseInt(r5.getText());
					Processor.reg6.value = Integer.parseInt(r6.getText());
					Processor.reg7.value = Integer.parseInt(r7.getText());
					
					while (!dataList.isEmpty()) {
						Data d = dataList.removeFirst();
						System.out.println("adding in memory " + d.getValue() + " at " + d.getAddress());
						Memory.store(d.getAddress(), d.getValue());
					}										
					System.out.println("width of " + Integer.parseInt(pipeline.getText()));
					Processor.m = Integer.parseInt(pipeline.getText());
										
					// loop through inst and add them to memory
					for (int i = 0; i < instList.size(); i++) {
						System.out.println("Add inst  " + instList.get(i).getType());
						Memory.storeInstructionUsingPC(i, instList.get(i));
					}
					
					int rSize = Integer.parseInt(reservStation.getText());
					System.out.println("Making Reservation stations " + rSize );
					for (int i = 0; i < rSize; i++) {
						Processor.reservationStations.add(new ReservationStation());
					}	
					
					Processor.instructionBufferSize = Integer.parseInt(insBuffer.getText());
					Processor.robSize = Integer.parseInt(rob.getText());
					
					int addSize = Integer.parseInt(addN.getText());
					int mulSize = Integer.parseInt(mulN.getText());
					int divSize = Integer.parseInt(divN.getText());
					
					System.out.println("Add FU " + addSize + " mul FU " + mulSize + " div FU " + divSize );
					for (int i = 0; i < addSize; i++) {
						Processor.functionalUnits.add(new FunctionalUnit(Instruction.ADD));
					}
					for (int i = 0; i < mulSize; i++) {
						Processor.functionalUnits.add(new FunctionalUnit(Instruction.MULT));
					}
					for (int i = 0; i < divSize; i++) {
						Processor.functionalUnits.add(new FunctionalUnit(Instruction.DIV));
					}										
					// run the simulation
					try {
						if (edu) {
							educationView();
						} else {
							simulationView();
						}						
					} catch (Exception e) {
						e.printStackTrace();
					}										
				}			
			}			
		});
		btnFinish.setBounds(650, 400, 89, 23);
		instPanel.add(btnFinish);
	}

	
	private void archiView() {
		archiPanel = new JPanel();
		archiPanel.setBounds(10, 11, 791, 440);		
		archiPanel.setLayout(null);
		
		JLabel lblMicroArchitecture = new JLabel("Micro Architecture:");
		lblMicroArchitecture.setFont(new Font("OCR A Extended", Font.BOLD | Font.ITALIC, 16));
		lblMicroArchitecture.setBounds(10, 11, 224, 33);
		archiPanel.add(lblMicroArchitecture);
		
		JLabel lblPipelineWidth = new JLabel("Pipeline width: ");
		lblPipelineWidth.setBounds(50, 75, 96, 14);
		archiPanel.add(lblPipelineWidth);
		
		JLabel lblRes = new JLabel("Number of reservation stations:");
		lblRes.setBounds(50, 111, 184, 14);
		archiPanel.add(lblRes);
		
		JLabel lblRobEntries = new JLabel("ROB entries:");
		lblRobEntries.setBounds(50, 150, 96, 14);
		archiPanel.add(lblRobEntries);
		
		JLabel lblFunctionalUnits = new JLabel("Functional Units:");
		lblFunctionalUnits.setBounds(50, 210, 116, 14);
		archiPanel.add(lblFunctionalUnits);
		
		JLabel lblAddsubUnits = new JLabel("ADD/SUB units:");
		lblAddsubUnits.setBounds(120, 235, 102, 14);
		archiPanel.add(lblAddsubUnits);
		
		JLabel lblMulUnits = new JLabel("MUL units:");
		lblMulUnits.setBounds(120, 260, 73, 14);
		archiPanel.add(lblMulUnits);
		
		JLabel lblDivUnits = new JLabel("DIV units:");
		lblDivUnits.setBounds(120, 285, 73, 14);
		archiPanel.add(lblDivUnits);
		
		JLabel lblExecutionTimein = new JLabel("Execution time (in cycles):");
		lblExecutionTimein.setBounds(370, 235, 149, 14);
		archiPanel.add(lblExecutionTimein);
		
		JLabel lblExecutionTimein_1 = new JLabel("Execution time (in cycles):");
		lblExecutionTimein_1.setBounds(370, 260, 149, 14);
		archiPanel.add(lblExecutionTimein_1);
		
		JLabel lblExecutionTimein_2 = new JLabel("Execution time (in cycles):");
		lblExecutionTimein_2.setBounds(370, 285, 149, 14);
		archiPanel.add(lblExecutionTimein_2);
		
		pipeline = new JTextField();
		pipeline.setBounds(162, 72, 44, 20);
		archiPanel.add(pipeline);
		pipeline.setColumns(10);
		
		reservStation = new JTextField();
		reservStation.setBounds(254, 108, 44, 20);
		archiPanel.add(reservStation);
		reservStation.setColumns(10);
		
		rob = new JTextField();
		rob.setBounds(136, 147, 44, 20);
		archiPanel.add(rob);
		rob.setColumns(10);
		
		addN = new JTextField();
		addN.setBounds(224, 232, 44, 20);
		archiPanel.add(addN);
		addN.setColumns(10);
		
		mulN = new JTextField();
		mulN.setBounds(224, 257, 44, 20);
		archiPanel.add(mulN);
		mulN.setColumns(10);
		
		divN = new JTextField();
		divN.setBounds(224, 282, 44, 20);
		archiPanel.add(divN);
		divN.setColumns(10);
		
		addEx = new JTextField();
		addEx.setBounds(529, 232, 44, 20);
		archiPanel.add(addEx);
		addEx.setColumns(10);
		
		mulEx = new JTextField();
		mulEx.setBounds(529, 257, 44, 20);
		archiPanel.add(mulEx);
		mulEx.setColumns(10);
		
		divEx = new JTextField();
		divEx.setBounds(529, 282, 44, 20);
		archiPanel.add(divEx);
		divEx.setColumns(10);
		
		final JLabel pipeReq = new JLabel("required");
		pipeReq.setForeground(Color.RED);
		pipeReq.setVisible(false);
		pipeReq.setFont(new Font("Tahoma", Font.ITALIC, 11));
		pipeReq.setBounds(338, 75, 46, 14);
		archiPanel.add(pipeReq);
		
		final JLabel rsReq = new JLabel("required");
		rsReq.setForeground(Color.RED);
		rsReq.setVisible(false);
		rsReq.setFont(new Font("Tahoma", Font.ITALIC, 11));
		rsReq.setBounds(359, 111, 46, 14);
		archiPanel.add(rsReq);
		
		final JLabel robReq = new JLabel("required");
		robReq.setForeground(Color.RED);
		robReq.setVisible(false);
		robReq.setFont(new Font("Tahoma", Font.ITALIC, 11));
		robReq.setBounds(234, 150, 46, 14);
		archiPanel.add(robReq);
		
		final JLabel addReq = new JLabel("required");
		addReq.setForeground(Color.RED);
		addReq.setVisible(false);
		addReq.setFont(new Font("Tahoma", Font.ITALIC, 11));
		addReq.setBounds(643, 235, 46, 14);
		archiPanel.add(addReq);
		
		final JLabel mulReq = new JLabel("required");
		mulReq.setForeground(Color.RED);
		mulReq.setVisible(false);
		mulReq.setFont(new Font("Tahoma", Font.ITALIC, 11));
		mulReq.setBounds(643, 260, 46, 14);
		archiPanel.add(mulReq);
		
		final JLabel divReq = new JLabel("required");
		divReq.setForeground(Color.RED);
		divReq.setVisible(false);
		divReq.setFont(new Font("Tahoma", Font.ITALIC, 11));
		divReq.setBounds(643, 285, 46, 14);
		archiPanel.add(divReq);
		
		JLabel lblInstructionBufferSize = new JLabel("Instruction buffer size:");
		lblInstructionBufferSize.setBounds(50, 175, 143, 14);
		archiPanel.add(lblInstructionBufferSize);
		
		insBuffer = new JTextField();
		insBuffer.setBounds(212, 175, 44, 20);
		archiPanel.add(insBuffer);
		insBuffer.setColumns(10);
		
		final JLabel lblRequired = new JLabel("required");
		lblRequired.setFont(new Font("Tahoma", Font.ITALIC, 11));
		lblRequired.setForeground(Color.RED);
		lblRequired.setVisible(false);
		lblRequired.setBounds(290, 175, 46, 14);
		archiPanel.add(lblRequired);
		
		JButton btnNext = new JButton("Next ->");
		btnNext.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				boolean valid = true;
				if (pipeline.getText().equals("")) {
					pipeReq.setVisible(true);
					valid = false;
				} else {
					pipeReq.setVisible(false);
				}
				if (insBuffer.getText().equals("")) {
					lblRequired.setVisible(true);
					valid = false;
				} else {
					pipeReq.setVisible(false);
				}
				if (reservStation.getText().equals("")) {
					rsReq.setVisible(true);
					valid = false;
				} else {
					rsReq.setVisible(false);
				}
				if (rob.getText().equals("")) {
					robReq.setVisible(true);
					valid = false;
				} else {
					robReq.setVisible(false);
				}
				if (addN.getText().equals("") || addEx.getText().equals("")) {
					addReq.setVisible(true);
					valid = false;
				} else {
					addReq.setVisible(false);
				}
				if (mulN.getText().equals("") || mulEx.getText().equals("")) {
					mulReq.setVisible(true);
					valid = false;
				} else {
					mulReq.setVisible(false);
				}
				if (divN.getText().equals("") || divEx.getText().equals("")) {
					divReq.setVisible(true);
					valid = false;
				} else {
					divReq.setVisible(false);
				}
				try {
					Integer.parseInt(pipeline.getText());
					Integer.parseInt(reservStation.getText());
					Integer.parseInt(rob.getText());
					Integer.parseInt(addN.getText());
					Integer.parseInt(addEx.getText());
					Integer.parseInt(mulN.getText());
					Integer.parseInt(mulEx.getText());
					Integer.parseInt(divN.getText());
					Integer.parseInt(divEx.getText());
				} catch (Exception e) {
					valid = false;
				}
				if (valid) {
					frame.getContentPane().removeAll();				
					frame.getContentPane().add(instPanel);
					frame.validate();
					frame.repaint();
				}
				
			}
		});
		btnNext.setBounds(650, 400, 89, 23);
		archiPanel.add(btnNext);
		
		JButton button = new JButton("<- Back");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				frame.getContentPane().removeAll();				
				frame.getContentPane().add(memoryPanel);
				frame.validate();
				frame.repaint();
			}
		});
		button.setBounds(30, 400, 89, 23);
		archiPanel.add(button);
		
	}

	
	private void memoryView() {
		memoryPanel = new JPanel();
		memoryPanel.setBounds(10, 11, 791, 440);		
		memoryPanel.setLayout(null);
		
		JLabel lblMemoryOrganization = new JLabel("Memory Organization:");
		lblMemoryOrganization.setFont(new Font("OCR A Extended", Font.BOLD | Font.ITALIC, 16));
		lblMemoryOrganization.setBounds(10, 11, 224, 33);
		memoryPanel.add(lblMemoryOrganization);
		
		JLabel lblMemoryCapacity = new JLabel("Memory Capacity (as 16-bit words):");
		lblMemoryCapacity.setBounds(47, 78, 203, 14);
		memoryPanel.add(lblMemoryCapacity);
		
		JLabel lblAccessTimein = new JLabel("Access time (in cycles):");
		lblAccessTimein.setBounds(47, 131, 167, 14);
		memoryPanel.add(lblAccessTimein);
		
		memCap = new JTextField();
		memCap.setBounds(286, 75, 44, 20);
		memoryPanel.add(memCap);
		memCap.setColumns(10);
		
		memTime = new JTextField();
		memTime.setBounds(196, 128, 44, 20);
		memoryPanel.add(memTime);
		memTime.setColumns(10);
		
		final JLabel memReq1 = new JLabel("required");
		memReq1.setForeground(Color.RED);
		memReq1.setVisible(false);
		memReq1.setFont(new Font("Tahoma", Font.ITALIC, 11));
		memReq1.setBounds(396, 78, 64, 14);
		memoryPanel.add(memReq1);
		
		final JLabel memReq2 = new JLabel("required");
		memReq2.setForeground(Color.RED);
		memReq2.setVisible(false);
		memReq2.setFont(new Font("Tahoma", Font.ITALIC, 11));
		memReq2.setBounds(396, 131, 64, 14);
		memoryPanel.add(memReq2);
		
		JButton btnNewButton = new JButton("Next ->");
		btnNewButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				boolean valid = true;				
				if (memTime.getText().equals("")) {
					memReq2.setVisible(true);
					valid = false;
				} else {
					memReq2.setVisible(false);
				}
				if (memCap.getText().equals("")) {
					memReq1.setVisible(true);
					valid = false;
				} else {
					memReq1.setVisible(false);
				}
				
				try {
					int n = Integer.parseInt(memCap.getText());					
					int n1 = n - 1;					
					if ((n & n1) != 0) {
						valid = false;
					}
					Integer.parseInt(memTime.getText());
					Integer.parseInt(memCap.getText());
				} catch (Exception e) {
					valid = false;
				}				
				if (valid) {
					frame.getContentPane().removeAll();				
					frame.getContentPane().add(archiPanel);
					frame.validate();
					frame.repaint();
				}
			}
		});		
		btnNewButton.setBounds(650, 400, 89, 23);
		memoryPanel.add(btnNewButton);
		
		JButton button = new JButton("<- Back");
		button.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				frame.getContentPane().removeAll();				
				frame.getContentPane().add(cachePanel);
				frame.validate();
				frame.repaint();
			}
		});
		button.setBounds(30, 400, 89, 23);
		memoryPanel.add(button);
		
	}

	
	
	private void cacheView() {
		cachePanel = new JPanel();
		cachePanel.setBounds(10, 11, 791, 440);		
		cachePanel.setLayout(null);
		
		JLabel lblCacheOrganization = new JLabel("Cache Organization:");
		lblCacheOrganization.setFont(new Font("OCR A Extended", Font.BOLD | Font.ITALIC, 16));
		lblCacheOrganization.setBounds(10, 11, 224, 33);
		cachePanel.add(lblCacheOrganization);
		
		JLabel lblCacheLevels = new JLabel("Cache Levels:");
		lblCacheLevels.setBounds(20, 55, 83, 14);
		cachePanel.add(lblCacheLevels);				
		
		JLabel level1 = new JLabel("Level 1:");
		level1.setBounds(35, 92, 46, 14);
		cachePanel.add(level1);
		
		JLabel lblSize = new JLabel("Size:");
		lblSize.setBounds(35, 117, 46, 14);
		cachePanel.add(lblSize);
		
		size1 = new JTextField();
		size1.setBounds(69, 114, 44, 20);
		cachePanel.add(size1);
		size1.setColumns(10);
		
		JLabel lblLine = new JLabel("Line:");
		lblLine.setBounds(138, 117, 46, 14);
		cachePanel.add(lblLine);
		
		line1 = new JTextField();
		line1.setBounds(175, 114, 44, 20);
		cachePanel.add(line1);
		line1.setColumns(10);
		
		JLabel lblAssotiativity = new JLabel("Associativity:");
		lblAssotiativity.setBounds(244, 117, 83, 14);
		cachePanel.add(lblAssotiativity);
		
		m1 = new JTextField();
		m1.setBounds(337, 114, 46, 20);
		cachePanel.add(m1);
		m1.setColumns(10);
		
		JLabel lblWritePolicy = new JLabel("Write Policy:");
		lblWritePolicy.setBounds(35, 142, 78, 14);
		cachePanel.add(lblWritePolicy);
		
		wb1 = new JCheckBox("Write Back");
		wb1.setBounds(136, 138, 98, 23);
		cachePanel.add(wb1);
		
		wth1 = new JCheckBox("Write Through");
		wth1.setBounds(254, 138, 107, 23);
		cachePanel.add(wth1);
		
		wb1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (wth1.isSelected()) {
					wth1.setSelected(false);
				}
			}
		});
		
		wth1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (wb1.isSelected()) {
					wb1.setSelected(false);
				}
			}
		});
		
		JLabel lblAccessTimein = new JLabel("Access time (in cycles):");
		lblAccessTimein.setBounds(35, 167, 149, 14);
		cachePanel.add(lblAccessTimein);
		
		time1 = new JTextField();
		time1.setBounds(207, 164, 46, 20);
		cachePanel.add(time1);
		time1.setColumns(10);
		
		final JLabel level2 = new JLabel("Level 2:");
		level2.setVisible(false);
		level2.setBounds(35, 192, 46, 14);
		cachePanel.add(level2);
		
		final JLabel sizeL2 = new JLabel("Size:");
		sizeL2.setVisible(false);
		sizeL2.setBounds(35, 217, 46, 14);
		cachePanel.add(sizeL2);
		
		size2 = new JTextField();
		size2.setBounds(69, 214, 44, 20);
		size2.setVisible(false);
		cachePanel.add(size2);
		size2.setColumns(10);
		
		final JLabel lineL2 = new JLabel("Line:");
		lineL2.setBounds(138, 217, 46, 14);
		lineL2.setVisible(false);
		cachePanel.add(lineL2);
		
		line2 = new JTextField();
		line2.setBounds(175, 214, 44, 20);
		line2.setVisible(false);
		cachePanel.add(line2);
		line2.setColumns(10);
		
		final JLabel assL2 = new JLabel("Associativity:");
		assL2.setBounds(244, 217, 83, 14);
		assL2.setVisible(false);
		cachePanel.add(assL2);
		
		m2 = new JTextField();
		m2.setBounds(339, 214, 44, 20);
		m2.setVisible(false);
		cachePanel.add(m2);
		m2.setColumns(10);
		
		final JLabel wp2 = new JLabel("Write Policy:");
		wp2.setBounds(35, 247, 78, 14);
		wp2.setVisible(false);
		cachePanel.add(wp2);
		
		wb2 = new JCheckBox("Write Back");
		wb2.setBounds(136, 238, 98, 23);
		wb2.setVisible(false);
		cachePanel.add(wb2);
		
		wth2 = new JCheckBox("Write Through");
		wth2.setBounds(254, 243, 107, 23);
		wth2.setVisible(false);
		cachePanel.add(wth2);
		
		wb2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (wth2.isSelected()) {
					wth2.setSelected(false);
				}
			}
		});
		
		wth2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (wb2.isSelected()) {
					wb2.setSelected(false);
				}
			}
		});
		
		final JLabel timeL2 = new JLabel("Acess time (in cycles):");
		timeL2.setBounds(35, 272, 149, 14);
		timeL2.setVisible(false);
		cachePanel.add(timeL2);
		
		time2 = new JTextField();
		time2.setBounds(209, 269, 44, 20);
		time2.setVisible(false);
		cachePanel.add(time2);
		time2.setColumns(10);
		
		final JLabel level3 = new JLabel("Level 3:");
		level3.setBounds(35, 297, 46, 14);
		level3.setVisible(false);
		cachePanel.add(level3);
		
		final JLabel sizeL3 = new JLabel("Size:");
		sizeL3.setBounds(35, 322, 46, 14);
		sizeL3.setVisible(false);
		cachePanel.add(sizeL3);
		
		size3 = new JTextField();
		size3.setBounds(69, 322, 44, 20);
		size3.setVisible(false);
		cachePanel.add(size3);
		size3.setColumns(10);
		
		final JLabel lineL3 = new JLabel("Line:");
		lineL3.setBounds(138, 322, 46, 14);
		lineL3.setVisible(false);
		cachePanel.add(lineL3);
		
		line3 = new JTextField();
		line3.setBounds(175, 319, 44, 20);
		line3.setVisible(false);
		cachePanel.add(line3);
		line3.setColumns(10);
		
		final JLabel assL3 = new JLabel("Associativity:");
		assL3.setBounds(244, 322, 83, 14);
		assL3.setVisible(false);
		cachePanel.add(assL3);
		
		m3 = new JTextField();
		m3.setBounds(339, 319, 44, 20);
		m3.setVisible(false);
		cachePanel.add(m3);
		m3.setColumns(10);
		
		final JLabel wp3 = new JLabel("Write Policy:");
		wp3.setBounds(35, 347, 78, 14);
		wp3.setVisible(false);
		cachePanel.add(wp3);
		
		wb3 = new JCheckBox("Write Back");
		wb3.setBounds(136, 343, 98, 23);
		wb3.setVisible(false);
		cachePanel.add(wb3);
		
		wth3 = new JCheckBox("Write Through");
		wth3.setBounds(249, 343, 112, 23);
		wth3.setVisible(false);
		cachePanel.add(wth3);
		
		wb3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (wth3.isSelected()) {
					wth3.setSelected(false);
				}
			}
		});
		
		wth3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (wb3.isSelected()) {
					wb3.setSelected(false);
				}
			}
		});
		
		final JLabel timeL3 = new JLabel("Acess time (in cycles):");
		timeL3.setBounds(35, 372, 149, 14);
		timeL3.setVisible(false);
		cachePanel.add(timeL3);
		
		time3 = new JTextField();
		time3.setBounds(209, 369, 44, 20);
		time3.setVisible(false);
		cachePanel.add(time3);
		time3.setColumns(10);			
				
		final JLabel req1 = new JLabel("all fields are required");
		req1.setFont(new Font("Tahoma", Font.ITALIC, 11));
		req1.setForeground(Color.RED);
		req1.setVisible(false);
		req1.setBounds(434, 117, 149, 14);
		cachePanel.add(req1);
		
		final JLabel w1 = new JLabel("selection required");
		w1.setFont(new Font("Tahoma", Font.ITALIC, 11));
		w1.setForeground(Color.RED);
		w1.setVisible(false);
		w1.setBounds(385, 142, 120, 14);
		cachePanel.add(w1);
		
		final JLabel t1 = new JLabel("time required");
		t1.setForeground(Color.RED);
		t1.setVisible(false);
		t1.setFont(new Font("Tahoma", Font.ITALIC, 11));
		t1.setBounds(295, 167, 98, 14);
		cachePanel.add(t1);
		
		final JLabel req2 = new JLabel("all fields are required");
		req2.setForeground(Color.RED);
		req2.setVisible(false);
		req2.setFont(new Font("Tahoma", Font.ITALIC, 11));
		req2.setBounds(434, 217, 120, 14);
		cachePanel.add(req2);
		
		final JLabel w2 = new JLabel("selection required");
		w2.setForeground(Color.RED);
		w2.setVisible(false);
		w2.setFont(new Font("Tahoma", Font.ITALIC, 11));
		w2.setBounds(385, 247, 98, 14);
		cachePanel.add(w2);
		
		final JLabel t2 = new JLabel("time required");
		t2.setForeground(Color.RED);
		t2.setVisible(false);
		t2.setFont(new Font("Tahoma", Font.ITALIC, 11));
		t2.setBounds(295, 272, 66, 14);
		cachePanel.add(t2);
		
		final JLabel req3 = new JLabel("all fields are required");
		req3.setForeground(Color.RED);
		req3.setVisible(false);
		req3.setFont(new Font("Tahoma", Font.ITALIC, 11));
		req3.setBounds(434, 322, 120, 14);
		cachePanel.add(req3);
		
		final JLabel w3 = new JLabel("selection required");
		w3.setForeground(Color.RED);
		w3.setVisible(false);
		w3.setFont(new Font("Tahoma", Font.ITALIC, 11));
		w3.setBounds(385, 347, 131, 14);
		cachePanel.add(w3);
		
		final JLabel t3 = new JLabel("time required");
		t3.setForeground(Color.RED);
		t3.setVisible(false);
		t3.setFont(new Font("Tahoma", Font.ITALIC, 11));
		t3.setBounds(295, 372, 88, 14);
		cachePanel.add(t3);
		
		levels = new JComboBox();		
		levels.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {				
				if (levels.getSelectedIndex() == 0) {
					level2.setVisible(false);
					sizeL2.setVisible(false);
					size2.setVisible(false);
					lineL2.setVisible(false);
					line2.setVisible(false);
					assL2.setVisible(false);
					m2.setVisible(false);
					wp2.setVisible(false);
					wb2.setVisible(false);
					wth2.setVisible(false);
					timeL2.setVisible(false);
					time2.setVisible(false);
					req2.setVisible(false);
					w2.setVisible(false);
					t2.setVisible(false);
					
					level3.setVisible(false);
					sizeL3.setVisible(false);
					size3.setVisible(false);
					lineL3.setVisible(false);
					line3.setVisible(false);
					assL3.setVisible(false);
					m3.setVisible(false);
					wp3.setVisible(false);
					wb3.setVisible(false);
					wth3.setVisible(false);
					timeL3.setVisible(false);
					time3.setVisible(false);
					req3.setVisible(false);
					w3.setVisible(false);
					t3.setVisible(false);
				} else if (levels.getSelectedIndex() == 1) {
					level2.setVisible(true);
					sizeL2.setVisible(true);
					size2.setVisible(true);
					lineL2.setVisible(true);
					line2.setVisible(true);
					assL2.setVisible(true);
					m2.setVisible(true);
					wp2.setVisible(true);
					wb2.setVisible(true);
					wth2.setVisible(true);
					timeL2.setVisible(true);
					time2.setVisible(true);
					
					level3.setVisible(false);
					sizeL3.setVisible(false);
					size3.setVisible(false);
					lineL3.setVisible(false);
					line3.setVisible(false);
					assL3.setVisible(false);
					m3.setVisible(false);
					wp3.setVisible(false);
					wb3.setVisible(false);
					wth3.setVisible(false);
					timeL3.setVisible(false);
					time3.setVisible(false);
					req3.setVisible(false);
					w3.setVisible(false);
					t3.setVisible(false);
				} else if (levels.getSelectedIndex() == 2) {
					level2.setVisible(true);
					sizeL2.setVisible(true);
					size2.setVisible(true);
					lineL2.setVisible(true);
					line2.setVisible(true);
					assL2.setVisible(true);
					m2.setVisible(true);
					wp2.setVisible(true);
					wb2.setVisible(true);
					wth2.setVisible(true);
					timeL2.setVisible(true);
					time2.setVisible(true);
					
					level3.setVisible(true);
					sizeL3.setVisible(true);
					size3.setVisible(true);
					lineL3.setVisible(true);
					line3.setVisible(true);
					assL3.setVisible(true);
					m3.setVisible(true);
					wp3.setVisible(true);
					wb3.setVisible(true);
					wth3.setVisible(true);
					timeL3.setVisible(true);
					time3.setVisible(true);
				} 
			}
		});		
		levels.setModel(new DefaultComboBoxModel(new String[] {"1", "2", "3"}));
		levels.setSelectedIndex(0);
		levels.setBounds(109, 55, 44, 20);
		cachePanel.add(levels);
		
		final JButton btnNext = new JButton("Next ->");
		btnNext.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				if (levels.getSelectedIndex() == 0) {
					boolean valid = true;					
					if (size1.getText().equals("") || m1.getText().equals("") || line1.getText().equals("")) {
						valid = false;						
						req1.setVisible(true);
					} else {
						req1.setVisible(false);
					}
					if (wb1.isSelected() || wth1.isSelected()) {
						w1.setVisible(false);
					} else {
						valid = false;
						w1.setVisible(true);						
					}
					if (time1.getText().equals("")) {
						t1.setVisible(true);
						valid = false;
					} else {
						t1.setVisible(false);
					}
					try {
						int s1 = Integer.parseInt(size1.getText());
						if ((s1 & (s1-1)) != 0) {
							valid = false;
						}
						int l1 = Integer.parseInt(line1.getText());
						int mn1 = Integer.parseInt(m1.getText());;
						if (l1 % mn1 != 0) {
							valid = false;
						}												
						Integer.parseInt(time1.getText());
					} catch(Exception e) {
						valid = false;
					}					
					if (valid) {
						frame.getContentPane().removeAll();				
						frame.getContentPane().add(memoryPanel);
						frame.validate();
						frame.repaint();
					}
				} else if (levels.getSelectedIndex() == 1) {
					boolean valid = true;					
					if (size1.getText().equals("") || m1.getText().equals("") || line1.getText().equals("")) {
						valid = false;
						req1.setVisible(true);
					} else {
						req1.setVisible(false);
					}
					if (wb1.isSelected() || wth1.isSelected()) {
						w1.setVisible(false);
					} else {
						valid = false;
						w1.setVisible(true);						
					}
					if (time1.getText().equals("")) {
						t1.setVisible(true);
						valid = false;
					} else {
						t1.setVisible(false);
					}
					if (size2.getText().equals("") || m2.getText().equals("") || line2.getText().equals("")) {
						valid = false;
						req2.setVisible(true);
					} else {
						req2.setVisible(false);
					}
					if (wb2.isSelected() || wth2.isSelected()) {
						w2.setVisible(false);
					} else {
						valid = false;
						w2.setVisible(true);						
					}
					if (time2.getText().equals("")) {
						t2.setVisible(true);
						valid = false;
					} else {
						t2.setVisible(false);
					}	
					try {
						int s1 = Integer.parseInt(size1.getText());
						if ((s1 & (s1-1)) != 0) {
							valid = false;
						}
						int l1 = Integer.parseInt(line1.getText());
						int mn1 = Integer.parseInt(m1.getText());;
						if (l1 % mn1 != 0) {
							valid = false;
						}
						Integer.parseInt(time1.getText());
						int s2 = Integer.parseInt(size2.getText());
						if ((s2 & (s2-1)) != 0) {
							valid = false;
						}
						int l2 = Integer.parseInt(line2.getText());
						int mn2 = Integer.parseInt(m2.getText());;
						if (l2 % mn2 != 0) {
							valid = false;
						}
						Integer.parseInt(time2.getText());
					} catch(Exception e) {
						valid = false;
					}		
					if (valid) {
						frame.getContentPane().removeAll();				
						frame.getContentPane().add(memoryPanel);
						frame.validate();
						frame.repaint();
					}
				} else if (levels.getSelectedIndex() == 2) {
					boolean valid = true;					
					if (size1.getText().equals("") || m1.getText().equals("") || line1.getText().equals("")) {
						valid = false;
						req1.setVisible(true);
					} else {
						req1.setVisible(false);
					}
					if (wb1.isSelected() || wth1.isSelected()) {
						w1.setVisible(false);
					} else {
						valid = false;
						w1.setVisible(true);						
					}
					if (time1.getText().equals("")) {
						t1.setVisible(true);
						valid = false;
					} else {
						t1.setVisible(false);
					}
					if (size2.getText().equals("") || m2.getText().equals("") || line2.getText().equals("")) {
						valid = false;
						req2.setVisible(true);
					} else {
						req2.setVisible(false);
					}
					if (wb2.isSelected() || wth2.isSelected()) {
						w2.setVisible(false);
					} else {
						valid = false;
						w2.setVisible(true);						
					}
					if (time2.getText().equals("")) {
						t2.setVisible(true);
						valid = false;
					} else {
						t2.setVisible(false);
					}
					if (size3.getText().equals("") || m3.getText().equals("") || line3.getText().equals("")) {
						valid = false;
						req3.setVisible(true);
					} else {
						req3.setVisible(false);
					}
					if (wb3.isSelected() || wth3.isSelected()) {
						w3.setVisible(false);
					} else {
						valid = false;
						w3.setVisible(true);						
					}
					if (time3.getText().equals("")) {
						t3.setVisible(true);
						valid = false;
					} else {
						t3.setVisible(false);
					}
					try {
						int s1 = Integer.parseInt(size1.getText());
						if ((s1 & (s1-1)) != 0) {
							valid = false;
						}
						int l1 = Integer.parseInt(line1.getText());
						int mn1 = Integer.parseInt(m1.getText());;
						if (l1 % mn1 != 0) {
							valid = false;
						}
						Integer.parseInt(time1.getText());
						int s2 = Integer.parseInt(size2.getText());
						if ((s2 & (s2-1)) != 0) {
							valid = false;
						}
						int l2 = Integer.parseInt(line2.getText());
						int mn2 = Integer.parseInt(m2.getText());;
						if (l2 % mn2 != 0) {
							valid = false;
						}
						Integer.parseInt(time2.getText());
						int s3 = Integer.parseInt(size3.getText());
						if ((s3 & (s3-1)) != 0) {
							valid = false;
						}
						int l3 = Integer.parseInt(line3.getText());
						int mn3 = Integer.parseInt(m3.getText());;
						if (l3 % mn3 != 0) {
							valid = false;
						}
						Integer.parseInt(time3.getText());
					} catch(Exception e) {
						valid = false;
					}		
					if (valid) {
						frame.getContentPane().removeAll();				
						frame.getContentPane().add(memoryPanel);
						frame.validate();
						frame.repaint();
					}
				}
			}			
		});
		btnNext.setBounds(650, 400, 89, 23);
		cachePanel.add(btnNext);
		
	}

	/**
	 * Launch the application.
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {		
		new GUI();				
	}	
	

}
